python脚本|云平台新增主机后,jumpserver自动导入主机信息
点击上方蓝字
jumpserver在之前几年就有使用过,之前用的没有web界面,最近在新公司也重新搭建了jumpserver,但是在主机导入上觉着有些麻烦,就看了下jumpserver对应的api,然后脚本导入相关的信息。
因为后面还会有新增的主机,所以每天也会去拉取云主机最新的列表,然后自动去导入到主机清单中。因为是根据系统名做了节点,所以有新的系统新增了主机,相应的节点信息也是没有的,所以会去查看节点是否存在,没有的话,也会自动建立。
本文中脚本内容可能不全或者不是很适应你的场景,详细的脚本内容可以后台私信获取。
♦️
认证
第一步 认证
调用jumpserver api的第一步还是要完成认证
官方也给了一些参考资料
大致分为三步
获取token--构建头信息--调用接口
这里以一个查看节点信息为例
#代码中ip根据自己的ip去替换,账户信息也根据自己的替换掉
class Jumpserver():
def get_token(self):
url = 'http://ip/api/v1/authentication/auth/'
query_args = {
"username" : "admin",
"password" : "admin",
}
requests.packages.urllib3.disable_warnings()
response = requests.post(url,data=query_args,verify=False)
#print (response.text)
return json.loads(response.text)['token']
def header_info(self):
#用户构建header头信息
token = self.get_token()
header_info = {"Authorization": 'Bearer ' + token}
#print (header_info)
return header_info
def get_node_list(self):
req = requests.get('http://192.168.200.6/api/v1/assets/nodes/' , headers=self.header_info(),verify=False)
node_list_json = json.loads(req.content.decode())
node_list_df = pd.DataFrame.from_records(
node_list_json, columns=["id", "name", "full_value", "key"])
node_list_df["full_value"] = node_list_df["full_value"].str.replace(
" ", "")
#print (type(node_list_df["full_value"]))
return node_list_df
if __name__ == '__main__':
a = Jumpserver()
b=a.get_node_list()
♦️
获取节点id,新的节点创建
因为我们的最终需求是要去创建新的ip信息,然后还要插入到已有的节点中
而不是默认的default下面,所以查看了相应的参数需求
具体api可以到 http://ip/api/docs 下面去查看
新建信息对应的api是assets
查看相关信息,必须的几个参数是:hostname、ip、platform
而我们前面提到的节点信息是需要具体的uuid,而不是自己拼接节点信息
所以在新插入一个信息之前,我们需要去获取对应的系统的节点信息,如果没有需要新建,并且新建好之后,还需要返回对应的值,具体的函数可以参考如下:
def get_nodeid_by_fullpath(self, fullpath):
#这个是获取节点的node_id的,即通过节点的路径,获取的node_id
#print (fullpath.split('[')[1].split(']')[0])
# 可以看到这个函数依赖于前面提到的查看node列表的函数
node_id = self.get_node_list()["full_value"] == fullpath
#print (node_id)
if node_id.any():
return self.get_node_list()[node_id]["id"].str.cat()
print ('1')
else:
print ('节点未建立')
print (fullpath)
nodeid= fullpath.split('/')[3]
env=fullpath.split('/')[2]
print (nodeid,env)
#这里对于没有建立的节点,调用了建立节点的函数,具体如下文
self.create_inode(nodeid,env)
node_id = self.get_node_list()["full_value"] == fullpath
#a=self.get_node_list()
return self.get_node_list()[node_id]["id"].str.cat()
建立新节点函数
def create_inode(self,nodename,env):
# 添加节点信息
#print (Config.prdid)
#下面这串url里面的一串字符是default节点的uuid,因为我的新节点是在default下面建立的
url = 'http://ip/api/v1/assets/nodes/4c713b57-372e-4cac-994d-25ee413a46e3/children/'
nodesData = {
"value":nodename,
}
#nodesData = json.dumps(nodesData)
print (url)
nodesreq = requests.post(url, headers=self.header_info(), data=nodesData,verify=False)
nodesreq = json.loads(nodesreq.text)
print(nodesreq)
♦️
新建主机信息
在获取了节点id之后
就可以根据接口需要的信息去拼接对应的data来实现插入数据了
因为我这边的ssh端口都不是默认的22,所以还需要制定端口协议
另外就是特权用户也是固定的,所以也指定了,这个特权用户,可以根据导出的数据获取。
下面就是导入数据的函数,会传入一个列表,列表是从csv文件中读取的,因为直接用的jumpserver导入模版,所以字段比较多
def create_asset(self,n):
#requests.packages.urllib3.disable_warnings()
node_id = n[27]
#print (node_id)
node_id = node_id.split("'")[1].split("'")[0]
#print (node_id)
node_id = self.get_nodeid_by_fullpath(node_id)
#print (node_id)
data= {
"ip" : n[1],
"hostname" : n[0],
"protocols" : ['ssh/2922'],
"is_active" : 'True',
"admin_user" : n[23],
"domain" : n[24],
"platform" : 'Linux',
"nodes" : node_id,
#"nodes_display" : n[i][27],
}
print (n)
print(n[24])
#print (data)
req = requests.post('http://ip/api/v1/assets/assets/',headers=self.header_info(),data=data,verify=False)
#req = requests.get('http://30.16.27.209/api/v1/assets/assets/',headers=self.header_info(),verify=False)
print (req.text)
print (req.status_code)
if req.status_code == 201:
logging.info("%s add success" % node_id)
print ("%s add success" % node_id)
else:
logging.info("%s fail" % node_id)
print ("%s fail" % node_id)
读取csv文件,获取列表函数
def readcsv(self):
data = list(csv.reader(open('test.csv','r')))
print (len(data))
for su in range(1,len(data)):
self.create_asset(data[su])
♦️
生成csv文件
这个第四步其实场景就不一样了
有些是第一次导入的情况,有些是新增数据
我们目前的情况是,不时会有新增的数据,新增的数据是在云平台上的
所以需要从云平台定时来取最新的数据,然后根据创建时间来判断是否是新的数据,然后生成对应数据的csv文件,因为一直用的是jumpserver 的导入模版,所以数据列比较多。
这部分仅提供了生成csv的参考脚本,可以根据需要去调整自己的生成方式。
#这个里面循环的result是我们从云平台拉出数据的一个字典
for i in range(len(result['body']['content'])):
values=[result['body']['content'][i]['name'],result['body']['content'][i]['portDetail'][0]['privateIp'],"Linux","['ssh/29022']","","","","","","","","","","","","","","","","","","","","","","60139add-4bee-43b8-8f1a-cb463ebe2fc5","","['/Default/sys']",""]
l1.append(values)
name1=["*主机名","*IP","*系统平台","协议组","协议","端口","激活","公网IP","资产编号","备注","制造商","型号","序列号","CPU型号","CPU数量","CPU核数","CPU总数","内存","硬盘大小","硬盘信息","操作系统","系统版本","系统架构","主机名原始","网域","特权用户","节点","节点名称","标签管理"]
test=pd.DataFrame(columns=name1,data=l1)
#print(test)
fn="jp_"+(time.strftime("%Y%m%d%H%M")+".csv")
test.to_csv(fn,encoding='gbk',index=False)
#如果csv文件没问题的话,可以直接在这边去调用那边的readcsv函数,完成数据的自动导入。
♦️
总结
当时做这个的背景是因为我们新搭建了jumpserver,但是主机量有很大,又不想手动去搞,所以花了点时间去研究了下
目前的话,有新的主机在云平台下单了,现在就直接更新了,然后可以直接在跳板机上登录了
还有部分没有介绍到,因为我们还分了不同的环境,实际上特权用户也是不同的,所以特权用户、节点名称等还涉及到了一个区分。
👆点击查看更多内容👆
推荐阅读
elk8.0部署文档(rsyslog+kafka+logstash+elasticsearch+kibana))
ELK告警插件-elastalert2 实践,支持elk8.0版本,企微机器人告警实现
记得星标记一下,下次更容易找到我